using System;
using System.Collections;
using System.Xml;

namespace ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Rule
{
	//*********************************************************************
	//
	// XMLRuless Class
	//
	// The XMLRuless class represents a collection 
	// base of XMLRules
	// Its imports methods from WAPI.XmlObjectSet like get set and add
	//
	//*********************************************************************
	public class XMLRulesFamily : bOSdotNET.XML.Data.XMLObjectSet 
	{
		public const string MAIN_NODE = "RulesFamily";

		private const string NAME_ATTRIBUTE = "Name";
		private const string DESCRIPTION_NODE = "Description";

		/** FIELDS **/		

		public string sName;
		public string sDescription;

		/** CONSTRUCTORS **/

		/** CONSTRUCTOR Empty **/
		public XMLRulesFamily()
		{
			this.Init();
		}

		/** CONSTRUCTOR Width xml parsering**/
		public XMLRulesFamily(System.Xml.XmlNode nodeList)
		{
			this.Parse(nodeList);
		}

		/** PROPERTIES **/

		public string Name 
		{
			get { return sName; }
			set { sName = value; }
		}

		public string Description
		{
			get { return sDescription; }
			set { sDescription = value; }
		}

		/** INSTANCE METHODS **/

		override public void Init()
		{
			sName= string.Empty;

			this.RemoveAll();
		}

		override public void Parse(System.Xml.XmlNode nodeList)
		{
			this.Init();

			System.Xml.XmlNode node;

			/** find the attributes situated on the root tag **/
			for ( int i=0; i<nodeList.Attributes.Count;i++)
			{
				node  =nodeList.Attributes.Item(i); 
				switch ( node.Name )
				{
					case XMLRulesFamily.NAME_ATTRIBUTE:
						sName = node.InnerText;
						break;
				}
			}

			for ( int i=0; i<nodeList.ChildNodes.Count;i++)
			{
				node = nodeList.ChildNodes[i];

				switch ( node.Name) 
				{
					case XMLRule.MAIN_NODE:
						this.Add ( new XMLRule(node));
						break;
					case XMLRulesFamily.DESCRIPTION_NODE:
						sDescription = node.InnerText;
						break;
				}
			}
		}

		/** Method for return a rule from collection **/
		public XMLRule Get(string sName)
		{
			XMLRule rule=null;

			for ( int i=0; i<this.List.Count; i++)
			{
				rule = (XMLRule)this.List[i];
				if ( rule.Name == sName )
				{
					return rule;
				}
			}

			throw new Exception.RuleNotFound(sName + " Not Found.");
		}

		public void RemoveByName(string sText)
		{
			XMLRule rule=null;

			for ( int i=0; i<this.List.Count; i++)
			{
				rule = (XMLRule)this.List[i];
				if ( rule.Name == sName )
				{
					this.RemoveAt (i);
					return;
				}
			}

			throw new Exception.RuleNotFound(sText + " Not Found.");
		}


		override public bOSdotNET.XML.XMLNode GetXMLNode()
		{
			bOSdotNET.XML.XMLNode xmlNode = new bOSdotNET.XML.XMLNode(XMLRulesFamily.MAIN_NODE);
			xmlNode.AddAttribute( new bOSdotNET.XML.XMLAttribute ( XMLRulesFamily.NAME_ATTRIBUTE , sName) );

			for ( int i=0; i<this.Count;i++)
			{
				xmlNode.AddNode ( this[i].GetXMLNode() );
			}

			return xmlNode;
		}

		
		/** WAPI Wrappers to call SCENARIO ENGINE **/

		/** no wapi **/

		/** SORTING  FIELDS **/

		public enum SortFields 
		{
			Name,
			Priority,
			Description
		}

		/** SORTING METHODS **/


		public void Sort(SortFields sortField, bool isAscending) 
		{
			switch (sortField) 
			{
				case SortFields.Name:
					InnerList.Sort(new NameComparer());
					break;
				case SortFields.Priority:
					InnerList.Sort(new PriorityComparer());
					break;
				case SortFields.Description:
					InnerList.Sort(new DescriptionComparer());
					break;
				
			}
			if (!isAscending) InnerList.Reverse();
		}


		private sealed class NameComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLRule first = (XMLRule) x;
				XMLRule second = (XMLRule) y;
				return first.Name.CompareTo(second.Name);
			}
		}

		private sealed class PriorityComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLRule first = (XMLRule) x;
				XMLRule second = (XMLRule) y;
				return first.Priority.CompareTo(second.Priority);
			}
		}

		private sealed class DescriptionComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLRule first = (XMLRule) x;
				XMLRule second = (XMLRule) y;
				return first.Description.CompareTo(second.Description);
			}
		}

	}
}